package com.alibaba.citrus.cr.forecast.facade.service;

import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.forecast.common.NumberTrimUtils;
import com.alibaba.citrus.cr.forecast.facade.converter.QueryForecastRequestConverter;
import com.alibaba.citrus.cr.forecast.functions.forecastorder.ability.PriceQueryUtils;
import com.alibaba.citrus.cr.forecast.repository.DealLineQueryRepository;
import com.alibaba.citrus.cr.forecast.repository.ForecastOrderLineQueryRepository;
import com.alibaba.citrus.cr.forecast.repository.ForecastOrderQueryRepository;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;

import com.epoch.app.bcorder.model.dto.GetScItemUnitInfoRequest;
import com.epoch.app.bcorder.model.dto.QueryGoodsListForForecastSaleRequest;
import com.epoch.app.bcorder.model.dto.QueryGoodsListRequest;
import com.epoch.app.bcorder.model.dto.QueryGoodsListResponse;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.PlatformEnhanceService;
import com.epoch.app.crb2btradecenter.api.orderlinequery.service.OrderLineQueryService;
import com.epoch.app.crb2btradecenter.dto.response.OrderLinePageQueryResponse;
import com.epoch.app.crb2btradecenter.model.dto.PageQueryOrderLineESListRequest;
import com.epoch.app.crforecastsales.api.forecastorderlinequery.service.ForecastOrderLineQueryService;
import com.epoch.app.crforecastsales.domian.deallinequeue.model.DealLineQueue;
import com.epoch.app.crforecastsales.domian.forecastorder.model.ForecastOrder;
import com.epoch.app.crforecastsales.domian.forecastorderline.dto.GetOrderLineByMainOrderIdRequest;
import com.epoch.app.crforecastsales.domian.forecastorderline.dto.GetOrderLineTotalByMainOrderIdRequest;
import com.epoch.app.crforecastsales.domian.forecastorderline.model.ForecastOrderLine;
import com.epoch.app.crforecastsales.domian.forecastorderline.service.ForecastOrderLineService;
import com.epoch.app.crforecastsales.dto.request.QueryGoodsDetailRequest;
import com.epoch.app.crforecastsales.dto.request.QueryListByDealStatusRequest;
import com.epoch.app.crforecastsales.dto.response.QueryForecastLineResponse;
import com.epoch.app.crforecastsales.dto.response.QueryGoodsDetailReponse;
import com.epoch.app.crforecastsales.forecastorderlineindex.model.ForecastOrderLineIndex;
import com.epoch.app.crforecastsales.model.dto.ActivitySDO;
import com.epoch.app.crforecastsales.model.dto.DealLineSDO;
import com.epoch.app.crforecastsales.model.dto.GetForecastQuantityListResponse;
import com.epoch.app.crforecastsales.model.dto.GetForecastQuantityResponse;
import com.epoch.app.crforecastsales.model.dto.GiftSDO;
import com.epoch.app.crforecastsales.model.dto.PageQueryForecastLineRequest;
import com.epoch.app.crforecastsales.model.dto.PageQueryForecastRequest;
import com.epoch.app.crforecastsales.model.dto.QueryGoodsDetailListRequest;
import com.epoch.app.crforecastsales.model.dto.QueryGoodsDetailListResponseResult;
import com.epoch.app.crforecastsales.model.dto.QuerySaleUnitRequest;
import com.epoch.app.crforecastsales.model.dto.SaleUnit;
import com.epoch.app.crforecastsales.model.dto.SearchForecastOrderRequest;
import com.epoch.app.crforecastsales.model.dto.SelectCombox;
import com.epoch.app.crforecastsales.model.dto.SubOrderInfo;
import com.epoch.app.crforecastsales.sdo.QueryGoodsDetailListResponse;
import com.epoch.app.crforecastsales.sdo.ScItemGoods;
import com.epoch.app.crforecastsales.sdo.SingleScGoods;
import com.epoch.app.crforecastsales.service.CrForecastSalesService;
import com.epoch.app.crplatformenhance.api.customerquery.service.CustomerQueryService;
import com.epoch.app.crplatformenhance.dictionaryquery.service.DictionaryQueryService;
import com.epoch.app.crplatformenhance.dto.request.CustomerRequest;
import com.epoch.app.crplatformenhance.goodsfavorites.dto.QueryGoodsFavoritesRequest;
import com.epoch.app.crplatformenhance.goodsfavorites.model.GoodsFavorites;
import com.epoch.app.crplatformenhance.goodsfavorites.service.GoodsFavoritesService;
import com.epoch.app.crplatformenhance.inventoryallotquery.service.InventoryAllotQueryService;
import com.epoch.app.crplatformenhance.model.dto.BaseEnumDTO;
import com.epoch.app.crplatformenhance.model.dto.BatchQueryAllotRequest;
import com.epoch.app.crplatformenhance.model.dto.GoodsFavoritesItem;
import com.epoch.app.crplatformenhance.model.dto.QueryDictionaryRequest;
import com.epoch.app.crplatformenhance.model.dto.QueryResolveInventoryResponse;
import com.epoch.app.crplatformenhance.sdo.CustomerSDO;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

@Service
@Primary
public class ForecastOrderLineQueryServiceImpl implements ForecastOrderLineQueryService {
    public static final String RECENT_USE = "99999999";
    public static final String RECENT_USE_TEXT = "近期使用";
    @Resource
    ForecastOrderLineQueryRepository forecastOrderLineQueryRepository;
    @Resource
    DealLineQueryRepository dealLineQueryRepository;
    @Resource
    ForecastOrderQueryRepository forecastOrderQueryRepository;
    @Autowired
    private InventoryAllotQueryService inventoryAllotQueryService;

    @Autowired
    private PlatformEnhanceService platformEnhanceService;
    @Autowired
    private BaseDataService baseDataService;

    @Autowired
    private OrderLineQueryService orderLineQueryService;

    @Autowired
    private CustomerQueryService customerQueryService;
    @Autowired
    DictionaryQueryService dictionaryQueryService;

    @Autowired
    private GoodsFavoritesService favoritesService;

    @Resource(name = "forecastSaleTaskExecutor")
    private ThreadPoolTaskExecutor scItemsQueryTaskExecutor;
    @Resource
    CrForecastSalesService forecastSalesService;
    @Resource
    ForecastOrderLineService forecastOrderLineService;
    /**
     * 价格查询工具
     */
    @Resource
    private PriceQueryUtils priceQueryUtils;

    private static Log log = Log.getLogger(ForecastOrderLineQueryServiceImpl.class);
    private static Map<String, String> customerMessage;

    /**
     * 分页查询预售子订单列表   袁登
     *
     * @param
     * @return
     */
    @Override
    @Deprecated
    public Result<List<QueryForecastLineResponse>> pageQuery(
        PageQueryForecastLineRequest pageQueryForecastLineRequest) {
        //        QueryForecastRequestConverter.toSearchForecastOrderRequest(pageQueryForecastLineRequest);
        //            PageResult<List<QueryForecastLineResponse>> listPageResult = forecastOrderLineQueryRepository
        //            .pageQuery(pageQueryForecastLineRequest);
        //            return Result.success(listPageResult.getContent());
        return Result.listEmptySuccess();
    }

    /**
     * 根据处理状态查询子订单
     * todo qjg 这个地方要进行优化，这个地方性能太差了
     *
     * @param queryListByDealStatusRequest
     * @return
     */
    @Override
    @FacadeInvoker
    public Result<List<QueryForecastLineResponse>> queryListByDealStatus(
        QueryListByDealStatusRequest queryListByDealStatusRequest) {
        try {
            DealLineSDO dealLineSDO = new DealLineSDO();
            dealLineSDO.setDealType(queryListByDealStatusRequest.getDealType().toString());//活动检查  分析
            //dealLineSDO.setDealStatus(queryListByDealStatusRequest.getDealStatus());
            //查到当天的
            Result<List<DealLineQueue>> listResult = dealLineQueryRepository.queryProgressQueueResult(dealLineSDO);
            if (CollectionUtils.isEmpty(listResult.getResult())) {
                return Result.listEmptySuccess();
            }
            //需求同一个预报分析明细只能展示一次
            List<String> collect = Nullable.stream(listResult.getResult()).map(it -> it.getForecastOrderLineId())
                .distinct().collect(Collectors.toList());
            /*PageResult<List<ForecastOrderLineSDO>> listPageResult = forecastOrderLineQueryRepository.batchLoadList
            (collect);*/
            SearchForecastOrderRequest searchForecastOrderRequest = new SearchForecastOrderRequest();
            searchForecastOrderRequest.setSubLineBizId(collect);
            //接口需要limit最200条刷新
            searchForecastOrderRequest.setLimit(200);
            Result<List<QueryForecastLineResponse>> listResult1 = forecastOrderLineQueryRepository.pageQuery(
                searchForecastOrderRequest);
            //            Map<String,QueryForecastLineResponse> forecastOrderLineSDOMap = listResult1.getResult()
            //            .stream().collect(Collectors.toMap(QueryForecastLineResponse::getId,o ->o));
            List<QueryForecastLineResponse> collect1 = listResult1.getResult().stream().map(it -> {
                for (DealLineQueue dealLineQueue : listResult.getResult()) {
                    if (Objects.equals(dealLineQueue.getForecastOrderLineId(), it.getId()))
                    //将队列中的订单回复状态给主单中
                    {
                        it.setReplyStatus(dealLineQueue.getDealStatus());
                        it.setModifierId(dealLineQueue.getCreator());
                        //                        it.setAnalysisTime(dealLineQueue.getGmtCreate());
                        it.setAnalysisTime(dealLineQueue.getGmt_create());
                    }
                }
                return it;
            }).collect(Collectors.toList());
            List<Future<QueryForecastLineResponse>> futureList = Lists.newArrayList();
            for (QueryForecastLineResponse queryForecastLineResponse : collect1) {
                CompletableFuture<QueryForecastLineResponse> future = CompletableFuture.supplyAsync(() -> {
                    try {
                        if (Objects.nonNull(queryForecastLineResponse.getCustomerCode())) {
                            CustomerRequest customerRequest = new CustomerRequest();
                            customerRequest.setCode(queryForecastLineResponse.getCustomerCode());
                            Result<CustomerSDO> customerSDOResult = customerQueryService.queryCustomer(customerRequest);
                            if (Objects.nonNull(customerSDOResult.getResult()) && Objects.nonNull(
                                customerSDOResult.getResult().getName())) {
                                queryForecastLineResponse.setCustomerName(customerSDOResult.getResult().getName());
                            }
                            if (Objects.isNull(queryForecastLineResponse.getAnalysisTime())) {
                                queryForecastLineResponse.setAnalysisTime(new Date());
                            }
                        }
                    } catch (Exception e) {
                        log.error("多线程查询客户异常", e);
                    }
                    return queryForecastLineResponse;
                }, scItemsQueryTaskExecutor);
                futureList.add(future);
            }

            List<QueryForecastLineResponse> responses = Lists.newArrayList();
            for (Future<QueryForecastLineResponse> queryForecastLineResponseFuture : futureList) {
                try {
                    QueryForecastLineResponse forecastOrderLineSDO = queryForecastLineResponseFuture.get();

                    //add by myw,准备添加sap销售单号，交货单号的返回
                    String forecastId = forecastOrderLineSDO.getMainOrderId();
                    String serialNumber = forecastOrderLineSDO.getSerialNumber();
                    PageQueryOrderLineESListRequest request = new PageQueryOrderLineESListRequest();
                    request.setFrontOrderId(forecastId);
                    request.setSerialNum(serialNumber);
                    request.setStart(0);
                    request.setLimit(1);
                    Result<List<OrderLinePageQueryResponse>> saleOrderList = orderLineQueryService.pageQueryES(request);
                    if (Objects.nonNull(saleOrderList) && CollectionUtils.isNotEmpty(saleOrderList.getResult())) {
                        String deliveryOrderId = saleOrderList.getResult().get(0).getDeliveryOrderId();
                        String sapSaleOrderId = saleOrderList.getResult().get(0).getSapSaleOrderId();
                        String saleOrderId = saleOrderList.getResult().get(0).getOrderBizId();
                        forecastOrderLineSDO.setSaleOrderId(saleOrderId);
                        forecastOrderLineSDO.setOuterLineId(sapSaleOrderId);
                        forecastOrderLineSDO.setDeliveryOrderId(deliveryOrderId);
                    }
                    //end of myw
                    responses.add(forecastOrderLineSDO);
                } catch (Exception e) {
                    // 异常处理
                    log.error("获取多线程查询结果异常", e);

                }
            }
            List<QueryForecastLineResponse> collect2 = Nullable.stream(responses).sorted(
                Comparator.comparing(QueryForecastLineResponse::getId).reversed()).sorted(
                Comparator.comparing(QueryForecastLineResponse::getAnalysisTime).reversed()).collect(
                Collectors.toList());
            return Result.success(collect2);
        } catch (Exception e) {
            log.error("查询队列列表异常", e);
            throw new FacadeException("OTS-04-001-00-15-028");
        }
    }

    @Override
    @FacadeInvoker
    public Result<QueryGoodsDetailReponse> queryGoodsDetail(QueryGoodsDetailRequest queryGoodsDetailReponseRequest) {
        QueryGoodsDetailReponse queryGoodsDetailReponse = new QueryGoodsDetailReponse();

        List<SubOrderInfo> forecastOrderLineSDOResultList = priceQueryUtils.queryGoodsDetail(
            queryGoodsDetailReponseRequest);

        queryGoodsDetailReponse.setForecastOrderLineSDOList(forecastOrderLineSDOResultList);
        return Result.success(queryGoodsDetailReponse);
    }

    /**
     * queryGoodsDetailList
     */
    @Override
    @FacadeInvoker
    public QueryGoodsDetailListResponseResult queryGoodsDetailList(
        QueryGoodsDetailListRequest queryGoodsDetailListRequest) {
        QueryGoodsDetailListResponseResult queryGoodsDetailListResponseResult
            = new QueryGoodsDetailListResponseResult();
        QueryGoodsDetailListResponse queryGoodsDetailListResponse = new QueryGoodsDetailListResponse();

        QueryGoodsListForForecastSaleRequest goodsListRequest = new QueryGoodsListForForecastSaleRequest();
        goodsListRequest.setTitle(
            StringUtils.isEmpty(queryGoodsDetailListRequest.getName()) ? null : queryGoodsDetailListRequest.getName());
        goodsListRequest.setOutIdList(queryGoodsDetailListRequest.getCodes());
        if (!StringUtils.isEmpty(queryGoodsDetailListRequest.getCode())){
            if (CollectionUtils.isNotEmpty(goodsListRequest.getOutIdList())){
                goodsListRequest.getOutIdList().add(queryGoodsDetailListRequest.getCode()) ;
            }else {
                goodsListRequest.setOutIdList(Collections.singletonList(queryGoodsDetailListRequest.getCode()));
            }
        }

        goodsListRequest.setRecentlyUsedItemIdList(queryGoodsDetailListRequest.getRecentlyUsedItemIdList());

        if (CollectionUtils.isEmpty(queryGoodsDetailListRequest.getGoodsFavoritesList())) {
            Result<List<GoodsFavorites>> goodsFavoritesResult = favoritesService.queryGoodsFavorites(
                new QueryGoodsFavoritesRequest());
            log.info("查询货品收藏夹出参:" + JSONObject.toJSONString(goodsFavoritesResult));
            if (Objects.nonNull(goodsFavoritesResult) && CollectionUtils.isNotEmpty(goodsFavoritesResult.getResult())) {
                GoodsFavorites goodsFavorites = goodsFavoritesResult.getResult().get(0);
                String goodsList = goodsFavorites.getGoodsList();
                if (org.apache.commons.lang3.StringUtils.isNotBlank(goodsList) && !"[]".equalsIgnoreCase(goodsList)) {
                    List<GoodsFavoritesItem> goodsFavoritesItems = JSONObject.parseArray(goodsList,
                        GoodsFavoritesItem.class);
                    List<String> goodsCodes = goodsFavoritesItems.stream().map(GoodsFavoritesItem::getGoodsCode)
                        .collect(Collectors.toList());
                    goodsListRequest.setGoodsFavoritesList(goodsCodes);
                }
            }
        } else {
            goodsListRequest.setGoodsFavoritesList(queryGoodsDetailListRequest.getGoodsFavoritesList());
        }

        Long l1 = System.currentTimeMillis();
        Result<List<QueryGoodsListResponse>> queryGoodsListResponse = platformEnhanceService.queryGoodsListForForecastSale(
            goodsListRequest);
        Long l2 = System.currentTimeMillis();
        log.info("query item 耗时:" + (l2 - l1));
        List<ScItemGoods> scItemGoodsList = new ArrayList<>();
        if (queryGoodsListResponse == null || queryGoodsListResponse.getResult() == null || CollectionUtils.isEmpty(
            queryGoodsListResponse.getResult())) {
            queryGoodsDetailListResponse.setScItemGoodsList(scItemGoodsList);
            queryGoodsDetailListResponse.setSuccess(true);
            queryGoodsDetailListResponseResult.setResult(queryGoodsDetailListResponse);
            queryGoodsDetailListResponseResult.setSuccess(true);
            return queryGoodsDetailListResponseResult;
        }
        List result = queryGoodsListResponse.getResult();
        scItemGoodsList = JSONObject.parseArray(JSONObject.toJSONString(result), ScItemGoods.class);
        //                getScItemUnitInfo

        //将货品id的集合统计出来
        Long l3 = System.currentTimeMillis();
        ArrayList<String> idsList = new ArrayList<>();

        //是否包含近期使用 lab
        //  boolean isIncludeRec=Boolean.FALSE;
        for (ScItemGoods scItemGoods : scItemGoodsList) {
            //            if (RECENT_USE.equalsIgnoreCase(scItemGoods.getValue())){
            //                isIncludeRec=Boolean.TRUE;
            //            }
            List<SingleScGoods> goodsList = scItemGoods.getGoodsList();
            if (CollectionUtils.isNotEmpty(goodsList)) {
                for (SingleScGoods singleScGoods : goodsList) {
                    String id = singleScGoods.getId();
                    if (!idsList.contains(id)) {
                        idsList.add(id);
                    }
                    List<SelectCombox> selectComboxes = new ArrayList<>();
                    if (!StringUtils.isEmpty(singleScGoods.getBaseUnitCode())) {
                        SelectCombox selectCombox1 = new SelectCombox();
                        selectCombox1.setValue(singleScGoods.getBaseUnitCode());
                        selectCombox1.setLabel(singleScGoods.getBaseUnitName());
                        selectCombox1.setExt("1");
                        selectComboxes.add(selectCombox1);

                    }
                    if (!CollectionUtils.isEmpty(selectComboxes)) {
                        singleScGoods.setSaleUnitList(selectComboxes);
                    }
                }
            }
        }
        //        if (!isIncludeRec){
        //            ScItemGoods recentScItemGoods=new ScItemGoods();
        //            recentScItemGoods.setValue(RECENT_USE);
        //            recentScItemGoods.setLabel(RECENT_USE_TEXT);
        //            recentScItemGoods.setGoodsList(new ArrayList<>());
        //            scItemGoodsList.add(0,recentScItemGoods);
        //        }

        Long l4 = System.currentTimeMillis();
        log.info("query unit 耗时:" + (l4 - l3));
        //获取每日库存的map todo ""是否需要判断？
        if (queryGoodsDetailListRequest.getDepartmentCode() == null
            && queryGoodsDetailListRequest.getChannelCode() == null
            && queryGoodsDetailListRequest.getOrganizationCode() == null
            && queryGoodsDetailListRequest.getSalesmanCode() == null) {
            //不进行每日库存接口调用
            //do nothing
        } else {
            BatchQueryAllotRequest queryResolveInventoryRequest = new BatchQueryAllotRequest();
            queryResolveInventoryRequest.setDepartmentCode(queryGoodsDetailListRequest.getDepartmentCode());
            queryResolveInventoryRequest.setChannelCode(queryGoodsDetailListRequest.getChannelCode());
            queryResolveInventoryRequest.setOrganizationCode(queryGoodsDetailListRequest.getOrganizationCode());
            //        queryResolveInventoryRequest.setSalesmanCode(queryGoodsDetailListRequest.getSaleChannelCode());
            queryResolveInventoryRequest.setSalesmanCode(queryGoodsDetailListRequest.getSalesmanCode());
            queryResolveInventoryRequest.setScItemList(idsList);
            queryResolveInventoryRequest.setWarehouseCode(queryGoodsDetailListRequest.getWarehouseCode());
            Result<QueryResolveInventoryResponse> queryResolveInventoryResponseResult = inventoryAllotQueryService
                .batchQueryAllot(queryResolveInventoryRequest);
            QueryResolveInventoryResponse result1 = queryResolveInventoryResponseResult.getResult();
            if (result1 != null) {
                Map<String, String> map = result1.getDailyInventoryMap();
                Map<String, Boolean> mapLimit = result1.getDailyInventoryLimitMap();
                //将每日库存的字段添加到集合中
                for (ScItemGoods scItemGoods : scItemGoodsList) {
                    List<SingleScGoods> goodsList = scItemGoods.getGoodsList();
                    for (SingleScGoods singleScGoods : goodsList) {
                        //默认每日库存是否限量为false
                        singleScGoods.setLimitSwitch(Boolean.FALSE);
                        String id = singleScGoods.getId();
                        if (map.containsKey(id)) {
                            String value = map.get(id);
                            if (!StringUtils.isEmpty(value)) {
                                BigDecimal dailyInventory = new BigDecimal(value);
                                String dailyInventoryStr = NumberTrimUtils.trimEndZeroOfBigDecimal(
                                    dailyInventory.setScale(3, RoundingMode.HALF_UP));
                                singleScGoods.setDailyInventory(dailyInventoryStr);
                            }
                        }
                        if (mapLimit.containsKey(id)) {
                            Boolean value = mapLimit.get(id);
                            if (Objects.nonNull(value)) {
                                singleScGoods.setLimitSwitch(value);
                            }
                        }
                    }
                }
            }
        }

        Long l5 = System.currentTimeMillis();
        log.info("query dailyInventory 耗时:" + (l5 - l4));
        queryGoodsDetailListResponse.setScItemGoodsList(scItemGoodsList);
        queryGoodsDetailListResponse.setSuccess(true);
        queryGoodsDetailListResponseResult.setResult(queryGoodsDetailListResponse);
        queryGoodsDetailListResponseResult.setSuccess(true);
        return queryGoodsDetailListResponseResult;
    }

    @Override
    @FacadeInvoker("查询预报子订单列表")
    //TODO:性能需要优化
    public Result<List<QueryForecastLineResponse>> pageQueryOrderLine(
        PageQueryForecastRequest pageQueryForecastRequest) {
        log.info("查询预报子订单列表ageQueryForecastRequest={}", JSON.toJSONString(pageQueryForecastRequest));
        SearchForecastOrderRequest searchForecastOrderRequest = QueryForecastRequestConverter
            .toSearchForecastOrderRequest(pageQueryForecastRequest);

        SearchForecastOrderRequest analysisReason = convertForecastAnalysisReason(searchForecastOrderRequest);
        log.info("analysisReason={}", JSON.toJSONString(analysisReason));
        Result<List<QueryForecastLineResponse>> listPageResult = forecastOrderLineQueryRepository.pageQuery(
            analysisReason);
        if (listPageResult.isSuccess() && CollectionUtils.isNotEmpty(listPageResult.getResult())) {
            List<QueryForecastLineResponse> list = listPageResult.getResult();
            for (QueryForecastLineResponse x : list) {
                Map features = x.getFeatures();
                if (features != null) {
                    if (features.get("activityDteails") != null && features.get("activityTag") != null) {
                        String activityStr = features.get("activityDteails").toString();
                        StringBuffer giftScItemCodes = new StringBuffer();
                        StringBuffer giftTotal = new StringBuffer();
                        String activityTag = features.get("activityTag").toString();
                        //activityTag=1 不显示
                        if (!activityTag.equals("1")) {
                            if (org.apache.commons.lang3.StringUtils.isNotBlank(activityStr)) {
                                List<ActivitySDO> activitySDOS = JSONArray.parseArray(activityStr, ActivitySDO.class);
                                if (CollectionUtils.isNotEmpty(activitySDOS)) {
                                    for (ActivitySDO ax : activitySDOS) {
                                        //disableChooseFlag true的时候不显示
                                        Boolean disableChooseFlag = false;
                                        if (ax.getDisableChooseFlag() != null) {
                                            disableChooseFlag = ax.getDisableChooseFlag();
                                        }
                                        if (CollectionUtils.isNotEmpty(ax.getChooseGiftList()) && ax.getIsSelect()
                                            .booleanValue() && !disableChooseFlag) {
                                            for (GiftSDO gx : ax.getChooseGiftList()) {
                                                giftScItemCodes.append(gx.getScItemCode()).append(",");
                                                giftTotal.append(gx.getGiftNumber()).append(gx.getGiftSalesUnit())
                                                    .append(
                                                        "/");
                                            }
                                        }
                                    }
                                }
                            }
                            String giftsNumStr = giftTotal.toString();
                            if (org.apache.commons.lang3.StringUtils.isNotBlank(giftsNumStr)) {
                                x.setGiftsNum(giftsNumStr.substring(0, giftsNumStr.length() - 1));
                            }
                            String giftScitemCodesStr = giftScItemCodes.toString();
                            if (org.apache.commons.lang3.StringUtils.isNotBlank(giftScitemCodesStr)) {
                                x.setGiftsScitemCodes(
                                    giftScitemCodesStr.substring(0, giftScitemCodesStr.length() - 1));
                            }
                        }
                    }
                }
            }
        }
        //2022.10.26 可用库存显示包含单位转换
        if (listPageResult != null && CollectionUtils.isNotEmpty(listPageResult.getResult())){
            listPageResult.getResult().forEach(queryForecastLineResponse -> {
                if (org.apache.commons.lang3.StringUtils.isNoneBlank(queryForecastLineResponse.getAvailableInventory(),
                        queryForecastLineResponse.getUnitConvert())){
                    //取可用库存 * 单位转换关系
                    queryForecastLineResponse.setAvailableInventory(new BigDecimal(queryForecastLineResponse.getAvailableInventory().trim())
                            .multiply(new BigDecimal(queryForecastLineResponse.getUnitConvert().trim()))
                            .setScale(3,RoundingMode.HALF_UP).toString());
                }
            });
        }
        return listPageResult;
    }

    @Override
    @FacadeInvoker
    public Result<List<SelectCombox>> querySaleUnitList(QuerySaleUnitRequest querySaleUnitListRequest) {
        GetScItemUnitInfoRequest getScItemUnitInfoRequest = new GetScItemUnitInfoRequest();
        getScItemUnitInfoRequest.setScItemId(querySaleUnitListRequest.getScItemId());
        Map map = (Map)baseDataService.getScItemUnitInfo(getScItemUnitInfoRequest);
        List<SelectCombox> selectComboxes = new ArrayList<>();
        if (map.get("result") != null) {
            //                        List<SaleUnit> saleUnits = (List<SaleUnit>) map.get("result");
            String js = JSON.toJSONString(map.get("result"));
            List<SaleUnit> saleUnits = JSONArray.parseArray(js, SaleUnit.class);
            if (CollectionUtils.isNotEmpty(saleUnits)) {
                selectComboxes = saleUnits.stream().map(saleUnit -> {
                    SelectCombox selectCombox = new SelectCombox();
                    selectCombox.setLabel(
                        saleUnit.getUnitName() == null ? saleUnit.getFeatures() : saleUnit.getUnitName());
                    selectCombox.setValue(saleUnit.getUnitCode());
                    selectCombox.setExt(saleUnit.getRelationNum().toString());
                    return selectCombox;
                }).collect(Collectors.toList());
            }
        }
        if (querySaleUnitListRequest.getInventoryUnit() != null
            && querySaleUnitListRequest.getInventoryUnitCode() != null
            && querySaleUnitListRequest.getUnitConvert() != null) {
            SelectCombox selectCombox = new SelectCombox();
            selectCombox.setLabel(querySaleUnitListRequest.getInventoryUnit());
            selectCombox.setValue(querySaleUnitListRequest.getInventoryUnitCode());
            selectCombox.setExt(querySaleUnitListRequest.getUnitConvert());
            selectComboxes.add(selectCombox);
        }
        Map<String, SelectCombox> stringSelectComboxMap = selectComboxes.stream().collect(
            Collectors.toMap(SelectCombox::getValue, o -> o, (k1, k2) -> k2));
        List<SelectCombox> list = new ArrayList<>(stringSelectComboxMap.values());
        return Result.listSuccess(list, list.size());

    }

    @Override
    public Result<GetForecastQuantityListResponse> queryForecastOrderLinesForReport(
        SearchForecastOrderRequest searchForecastOrderRequest) {
        Result<List<ForecastOrderLineIndex>> listResult =
            forecastOrderLineQueryRepository.queryForecastOrderLinesForReport(searchForecastOrderRequest);
        if (Objects.isNull(listResult)) {
            return Result.success(new GetForecastQuantityListResponse());
        }
        List<ForecastOrderLineIndex> list = listResult.getResult();
        if (CollectionUtils.isEmpty(list)) {
            return Result.success(new GetForecastQuantityListResponse());
        }
        GetForecastQuantityListResponse result = new GetForecastQuantityListResponse();
        List<GetForecastQuantityResponse> responses = Lists.newArrayList();
        try {
            list.forEach(e -> {
                if (Objects.nonNull(e)) {
                    GetForecastQuantityResponse getForecastQuantityResponse = new GetForecastQuantityResponse();
                    getForecastQuantityResponse.setOrgId(e.getMainBisUnitCode());

                    Integer quantity = StringUtils.isEmpty(e.getSubQuantity()) ? 0 : Integer.valueOf(
                        e.getSubQuantity());
                    getForecastQuantityResponse.setQuantity(quantity);

                    Integer actualTotalReplyAmount = Objects.isNull(e.getSubActualTotalReplyAmount()) ? 0
                        : Integer.valueOf(e.getSubActualTotalReplyAmount() + "");
                    getForecastQuantityResponse.setActualTotalReplyAmount(actualTotalReplyAmount);

                    Integer detailStatus = Objects.isNull(e.getSubStatus()) ? null : Integer.valueOf(
                        e.getSubStatus() + "");
                    getForecastQuantityResponse.setDetailStatus(detailStatus);

                    Integer mainStatus = Objects.isNull(e.getMainStatus()) ? null : Integer.valueOf(
                        e.getMainStatus() + "");
                    getForecastQuantityResponse.setMainStatus(mainStatus);

                    getForecastQuantityResponse.setDepartmentCode(e.getMainDepartmentCode());
                    getForecastQuantityResponse.setDepartmentName(e.getMainDepartmentName());
                    getForecastQuantityResponse.setChannelCode(e.getMainChannelCode());
                    getForecastQuantityResponse.setChannelName(e.getMainChannelName());
                    getForecastQuantityResponse.setId(e.getSubId() + "");

                    Long vaildBeginTime = e.getMainVaildBeginTime();
                    if (Objects.nonNull(vaildBeginTime)) {
                        getForecastQuantityResponse.setVaildBeginTime(
                            new Date(Long.parseLong(String.valueOf(vaildBeginTime))));
                    }

                    getForecastQuantityResponse.setRefuseReason(e.getSubRefuseReason());
                    getForecastQuantityResponse.setRefuseReasonCode(e.getSubRefuseReasonCode());
                    if (Objects.nonNull(e.getSubUnitPrice())) {
                        getForecastQuantityResponse.setAmount(new BigDecimal(e.getSubUnitPrice()));
                    }
                    if (Objects.nonNull(e.getSubTotalFee())) {
                        getForecastQuantityResponse.setTotalAmount(new BigDecimal(e.getSubTotalFee()));
                    }

                    getForecastQuantityResponse.setUnitConvert(e.getSubUnitConvert());
                    responses.add(getForecastQuantityResponse);
                }
            });
        } catch (Exception e) {
            log.error("error msg: ", e);
        }
        result.setList(responses);
        return Result.success(result);
    }

    private SearchForecastOrderRequest convertForecastAnalysisReason(SearchForecastOrderRequest request) {
        if (CollectionUtils.isEmpty(request.getAnalysisReasonCodeList())) {
            return request;
        }
        QueryDictionaryRequest queryDictionaryRequest = new QueryDictionaryRequest();
        queryDictionaryRequest.setDictCode("analyReason");
        Result<List<BaseEnumDTO>> result = dictionaryQueryService.queryValues(queryDictionaryRequest);
        if (result == null || CollectionUtils.isEmpty(result.getResult())) {
            throw new RuntimeException("查询分析原因为空");
        }
        Map<String, String> map = result.getResult().stream().collect(
            Collectors.toMap(BaseEnumDTO::getValue, BaseEnumDTO::getLabel, (key1, key2) -> key2));
        List<String> analysisCodeList = Lists.newArrayList();
        request.getAnalysisReasonCodeList().forEach(code ->
            analysisCodeList.add(map.get(code)));
        request.setAnalysisReasonCodeList(analysisCodeList);
        return request;
    }

    @Override
    public Result<String> sumMoneyOrderLine(SearchForecastOrderRequest searchForecastOrderRequest) {
        Long totalFee=0l;
        log.info("sumMoneyOrderLine_usetime:{}sqlstart",System.currentTimeMillis());
        Result<Integer> mainOrderTotalResult=forecastSalesService.countForecastOrderForMini(searchForecastOrderRequest);
        if(mainOrderTotalResult.getResult()!=null&&mainOrderTotalResult.getResult()==0){
            return Result.success(totalFee.toString());
        }
        List<String> mainOrderIds=new ArrayList<>();
        int total=mainOrderTotalResult.getResult();
        int size=1000;
        int start=0;
        for(int i=0;i<size;i++){
            start=i*size;
            if(start>total){
                break;
            }
            searchForecastOrderRequest.setStart(start);
            searchForecastOrderRequest.setLimit(size);
            Result<List<ForecastOrder>> mainOrderIdsResult=forecastSalesService.queryForecastOrderIdForMini(searchForecastOrderRequest);
            if(CollectionUtils.isEmpty(mainOrderIdsResult.getResult())){
                return Result.success(totalFee.toString());
            }
            mainOrderIdsResult.getResult().forEach(x->mainOrderIds.add(x.getId().toString()));
        }
        log.info("sumMoneyOrderLine_mainOrderListsize:{}start",mainOrderIds.size());
        GetOrderLineTotalByMainOrderIdRequest totalRequest=new GetOrderLineTotalByMainOrderIdRequest();
        totalRequest.setIds(mainOrderIds);
        Result<Integer> childOrderTotalResult=forecastOrderLineService.getOrderLineTotalByMainOrderId(totalRequest);
        if(childOrderTotalResult.getResult()!=null&&childOrderTotalResult.getResult()==0){
            return Result.success(totalFee.toString());
        }

        List<ForecastOrderLine> childList=new ArrayList<>();
        int childtotal=childOrderTotalResult.getResult();
        int childStart=0;
        for(int i=0;i<size;i++){
            childStart=i*size;
            if(childStart>childtotal){
                break;
            }
            GetOrderLineByMainOrderIdRequest getOrderLineByMainOrderIdRequest=new GetOrderLineByMainOrderIdRequest();
            getOrderLineByMainOrderIdRequest.setStart(childStart);
            getOrderLineByMainOrderIdRequest.setLimit(size);
            getOrderLineByMainOrderIdRequest.setIds(mainOrderIds);
            Result<List<ForecastOrderLine>> childOrderInfoResult=forecastOrderLineService.getOrderLineByMainOrderId(getOrderLineByMainOrderIdRequest);
            if(CollectionUtils.isEmpty(childOrderInfoResult.getResult())){
               continue;
            }
            childList.addAll(childOrderInfoResult.getResult());
        }
        log.info("sumMoneyOrderLine_usetime:{}sqlEnd,childListsize:{}",System.currentTimeMillis(),childList.size());
        log.info("sumMoneyOrderLine_usetime:{}start",System.currentTimeMillis());
        boolean sumAllChildOrder=true;
        if(org.apache.commons.collections.CollectionUtils.isNotEmpty(searchForecastOrderRequest.getMainStatusList())){
            sumAllChildOrder=false;
        }
        for(ForecastOrderLine x:childList){
            switch (x.getStatus()){
                case 3:
                    if(sumAllChildOrder){
                        totalFee += x.getTotalFee();
                    }else {
                        //部分回复 取未回复数量*金额
                        if (org.apache.commons.lang3.StringUtils.isNotBlank(x.getQuantity()) && x.getActualTotalReplyAmount() != null) {
                            Integer quantity = Integer.parseInt(x.getQuantity());
                            int waitReplyQuantity = quantity - x.getActualTotalReplyAmount();
                            long waitReplyFee = waitReplyQuantity * x.getUnitPrice();
                            totalFee += waitReplyFee;
                        }
                    }
                    break;
                //待回复 取总金额即可 不用计算数量
                //ForecastLineStatusEnum.WAITING_FOR_REPLY.getNumValue().intValue()
                case 2:
                    totalFee+=x.getTotalFee();
                    break;
                case 4:
                    if(sumAllChildOrder&& org.apache.commons.lang3.StringUtils.isEmpty(x.getRefuseReasonCode())) {
                        totalFee += x.getTotalFee();
                    }
                    break;
            }
        }
        log.info("sumMoneyOrderLine_usetime:{}end",System.currentTimeMillis());
        return Result.success(totalFee.toString());
    }
}
